// -*-mode:c++; coding:utf-8-*-

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>

#include <xbase_utility.hpp>
#include <naming_strategy.hpp>
#include <logger.hpp>

#include "protocol.hpp"
#include "io_service_pool_impl.hpp"
#include "session_manager.hpp"
#include "location_cache.hpp"
#include "root_meta_cache.hpp"

using namespace xbase;

typedef boost::system::error_code error_code;

void on_get_meta_data(location_cache *lc,
					  string *table_name,
					  string *request_row,
					  protocol::tablet_info_ptr tablet_info_p,
					  protocol::server_address_ptr server_address_p,
					  const error_code& ec)
{
	if(ec)
	{
		cerr << "get meta data failed : " << ec << " - " << ec.message() << endl;
	}
	else
	{
		cerr << "tabletInfo: " << tablet_info_p->to_string() << endl;
		cerr << "serverAddress: " << server_address_p->to_string() << endl;
	}	
}

int main(int argc, char **argv)
{
	if(argc!=3)
	{
		cerr <<argv[0]<<" master_ip master_port"<< endl;
		return 0;
	}

	LOG_CONFIG("../../conf/log4cplus.tablet_server.conf");

	boost::asio::ip::tcp::endpoint endpoint(
		boost::asio::ip::address::from_string(argv[1]),
		::atoi(argv[2])
		);

	string table_name;
	string request_row;
	bool hard_search;

	boost::shared_ptr<io_service_pool> pool(new impl::single_io_service());
	client_options options;
	pool->set_options(options);
	pool->run();

	session_manager sm(*pool);

	root_meta_cache rmc(*pool, endpoint, sm);
	location_cache lc(*pool, rmc, sm);

	std::string input;
	while(std::cin >> input)
	{
		if (input == "search")
		{
			cout<<"table_name: ";
			cin>>table_name;
			cout<<"request_row: ";
			cin>>request_row;
			cout<<"hard_search: ";
			cin>>hard_search;

			lc.async_get_meta(boost::bind(on_get_meta_data, &lc, &table_name, &request_row, _1, _2, _3), table_name, request_row, hard_search, cur_micro_seconds());
		}
		else if(input == "close")
		{
			sm.close();
		}
		else if(input == "quit")
		{
			break;
		}
	}

	pool->stop();
	pool->join();

	return 0;
}
